﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Metabase.MetabaseObjects
{
    public class MetabaseObject : IMetabaseObject
    {
        public object ID;
        public object External_ID;
        public object Parent_ID;
        public object Type_ID;
        public object Type_Name;
        public object Object_Name;
        public object Description;
        public object Modify_Date;
        public MetabaseHandler metabaseHandler;

        public void CreateObject()
        {
            // Добавим новый объект
            string commandText = "mb_CreateObject";
            using (SqlCommand dbCommand = new SqlCommand(commandText, metabaseHandler.dbHandler.connection))
            {
                dbCommand.CommandType = CommandType.StoredProcedure;
                dbCommand.Parameters.Add("External_ID", SqlDbType.NVarChar).Value = External_ID == null ? DBNull.Value : External_ID;
                dbCommand.Parameters.Add("Parent_ID", SqlDbType.Int).Value = Parent_ID == null ? DBNull.Value : Parent_ID;
                dbCommand.Parameters.Add("Type_ID", SqlDbType.Int).Value = Type_ID;
                dbCommand.Parameters.Add("Object_Name", SqlDbType.NVarChar).Value = Object_Name;
                dbCommand.Parameters.Add("Description", SqlDbType.NVarChar).Value = Description == null ? DBNull.Value : Description;
                SqlParameter out_Id = dbCommand.Parameters.Add("Id", SqlDbType.Int);
                out_Id.Direction = ParameterDirection.Output;
                dbCommand.ExecuteNonQuery();
                ID = out_Id.Value;
            }
            // Если не был задан его External_ID, то сгенерируем новый
            if (External_ID == null)
            {
                External_ID = "OBJ" + ID;
            }
            commandText = "mb_UpdateObject";
            using (SqlCommand dbCommand = new SqlCommand(commandText, metabaseHandler.dbHandler.connection))
            {
                dbCommand.CommandType = CommandType.StoredProcedure;
                dbCommand.Parameters.Add("External_ID", SqlDbType.NVarChar).Value = External_ID;
                dbCommand.Parameters.Add("Parent_ID", SqlDbType.Int).Value = Parent_ID == null ? DBNull.Value : Parent_ID;
                dbCommand.Parameters.Add("Type_ID", SqlDbType.Int).Value = Type_ID;
                dbCommand.Parameters.Add("Object_Name", SqlDbType.NVarChar).Value = Object_Name;
                dbCommand.Parameters.Add("Description", SqlDbType.NVarChar).Value = Description == null ? DBNull.Value : Description;
                dbCommand.Parameters.Add("Id", SqlDbType.Int).Value = ID;
                dbCommand.ExecuteNonQuery();
            }
        }

        // Процедура удаления дочерних объектов
        private void DeleteChildObjects(int Parent_ID)
        {
            List<MetabaseObject> metabaseObjectList = new List<MetabaseObject>();
            // Получим список дочерних объектов
            string queryText = "select * from mb_MetabaseStructure where Parent_ID = @Parent_ID";
            using (SqlCommand dbCommand = new SqlCommand(queryText, metabaseHandler.dbHandler.connection))
            {
                dbCommand.Parameters.Add("Parent_ID", SqlDbType.Int).Value = Parent_ID;
                SqlDataReader cursor = dbCommand.ExecuteReader();
                while (cursor != null && cursor.Read())
                {
                    // Добавим новый объект в список удаления
                    MetabaseObject metaObject = new MetabaseObject
                    {
                        ID = cursor["ID"],
                        External_ID = cursor["External_ID"],
                        Parent_ID = cursor["Parent_ID"],
                        Type_ID = cursor["Type_ID"],
                        Object_Name = cursor["Object_Name"],
                        Description = cursor["Description"],
                        metabaseHandler = metabaseHandler,
                    };
                    metabaseObjectList.Add(metaObject);
                }
                cursor.Close();
            }
            // Рекурсивно удалим дочерние объекты
            foreach (MetabaseObject metabaseObject in metabaseObjectList)
            {
                DeleteChildObjects((int)metabaseObject.ID);
                // Удалим текущий объект
                DeleteCurrentObject((int)metabaseObject.ID);
            }
        }

        // Процедура удаления текущего объекта
        private void DeleteCurrentObject(int ID)
        {
            string commandText = "exec mb_DeleteObject @ID";
            using (SqlCommand dbCommand = new SqlCommand(commandText, metabaseHandler.dbHandler.connection))
            {
                dbCommand.Parameters.Add("ID", SqlDbType.Int).Value = (int)ID;
                dbCommand.ExecuteNonQuery();
            }
        }

        public void DeleteObject()
        {
            // Рекурсино удалим дочерние объекты
            DeleteChildObjects((int)ID);
            // Удалим текущий объект
            DeleteCurrentObject((int)ID);
        }

        public void EditObject()
        {
            string commandText = "mb_UpdateObject";
            using (SqlCommand dbCommand = new SqlCommand(commandText, metabaseHandler.dbHandler.connection))
            {
                dbCommand.CommandType = CommandType.StoredProcedure;
                dbCommand.Parameters.Add("External_ID", SqlDbType.NVarChar).Value = External_ID;
                dbCommand.Parameters.Add("Parent_ID", SqlDbType.Int).Value = Parent_ID == null ? DBNull.Value : Parent_ID;
                dbCommand.Parameters.Add("Type_ID", SqlDbType.Int).Value = Type_ID;
                dbCommand.Parameters.Add("Object_Name", SqlDbType.NVarChar).Value = Object_Name;
                dbCommand.Parameters.Add("Description", SqlDbType.NVarChar).Value = Description == null ? DBNull.Value : Description;
                dbCommand.Parameters.Add("Id", SqlDbType.Int).Value = ID;
                dbCommand.ExecuteNonQuery();
            }
        }
    }
}
